package timing.ukulele.user.service;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.ShearCaptcha;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import timing.ukulele.common.data.ResponseCode;
import timing.ukulele.common.data.ResponseData;
import timing.ukulele.data.user.view.UserVO;
import timing.ukulele.facade.portal.feign.RoleFeignFacade;
import timing.ukulele.persistence.service.BaseService;
import timing.ukulele.user.mapper.SysUserMapper;
import timing.ukulele.user.persistent.SysThirdPartyUser;
import timing.ukulele.user.persistent.SysUser;

import java.util.*;

import static timing.ukulele.user.config.TopicConfig.PASSWORD_CHANNEL;
import static timing.ukulele.user.config.TopicConfig.PASSWORD_ROUTING;

@Service
public class SysUserService extends BaseService<SysUserMapper, SysUser> {
    private final SysThirdPartyUserService thirdPartyUserService;
    private final AmqpTemplate rabbitTemplate;
    private final RoleFeignFacade roleFeignFacade;

    public SysUserService(SysThirdPartyUserService thirdPartyUserService,
                          AmqpTemplate rabbitTemplate, RoleFeignFacade roleFeignFacade) {
        this.thirdPartyUserService = thirdPartyUserService;
        this.rabbitTemplate = rabbitTemplate;
        this.roleFeignFacade = roleFeignFacade;
    }

    /**
     * 根据用户名查询用户
     *
     * @param username 用户名
     * @return SysUser 用户信息
     */
    public SysUser getUserByUserName(String username) {
        SysUser user = this.lambdaQuery().eq(SysUser::getUsername, username).one();
        return user;
    }

    /**
     * 根据电话号码查询用户
     *
     * @param phone 电话号码
     * @return SysUser 用户信息
     */
    public SysUser getUserByPhone(String phone) {
        SysUser user = this.lambdaQuery().eq(SysUser::getPhone, phone).one();
        return user;
    }

    /**
     * 根据电话号码或用户名查询用户信息
     *
     * @param phoneOrName 电话号码
     * @return 用户信息
     */
    public SysUser getUserByPhoneOrName(String phoneOrName) {
        SysUser user = this.lambdaQuery().eq(SysUser::getUsername, phoneOrName).or().eq(SysUser::getPhone, phoneOrName).one();
        return user;
    }

    /**
     * 多条件查询用信息
     *
     * @param map 用户条件，key须与表属性对应
     * @return 用户列表
     */
    public List<SysUser> getUserByParam(Map<String, Object> map) {
        List<SysUser> userList = super.listByMap(map);
        return userList;
    }

    public IPage<UserVO> getPage(String username, String phone, String label, String name, String email, Boolean deleted, int current, int size) {
        Page<SysUser> page = new Page<>(current, size);
        LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<>();
        if (StringUtils.hasText(username))
            query.likeRight(SysUser::getUsername, username);
        if (StringUtils.hasText(phone))
            query.likeRight(SysUser::getPhone, phone);
        if (StringUtils.hasText(label))
            query.eq(SysUser::getLabel, label);
        if (StringUtils.hasText(name))
            query.likeRight(SysUser::getName, name);
        if (StringUtils.hasText(email))
            query.likeRight(SysUser::getEmail, email);
        if (deleted != null)
            query.eq(SysUser::getDeleted, deleted);
        query.orderByDesc(SysUser::getId);
        IPage<SysUser> iPage = this.getBaseMapper().selectPage(page, query);
        Page<UserVO> voPage = new Page<>(current, size);
        if (iPage != null && !CollectionUtils.isEmpty(iPage.getRecords())) {
            List<UserVO> voList = new ArrayList<>(iPage.getRecords().size());
            iPage.getRecords().forEach(po -> {
                UserVO vo = new UserVO();
                BeanUtils.copyProperties(po, vo);
                po.setPassword(null);
                voList.add(vo);
            });
            voPage.setPages(iPage.getPages());
            voPage.setTotal(iPage.getTotal());
            voPage.setRecords(voList);
        }
        return voPage;
    }

    @Transactional(rollbackFor = Exception.class)
    public ResponseData<String> registerUser(UserVO user, Boolean sendMessage) {
        List<SysUser> existUsers = this.lambdaQuery().or().eq(SysUser::getUsername, user.getUsername()).or().eq(SysUser::getPhone, user.getPhone()).list();
        if (!CollectionUtils.isEmpty(existUsers)) {
            if (existUsers.stream().anyMatch(item -> item.getUsername().equalsIgnoreCase(user.getUsername())))
                return new ResponseData<>(ResponseCode.ERROR.getCode(), "该用户名已被使用，请更换");
            if (existUsers.stream().anyMatch(item -> item.getPhone().equalsIgnoreCase(user.getPhone())))
                return new ResponseData<>(ResponseCode.ERROR.getCode(), "该手机号已被使用，请更换");
        }
        SysUser userPO = new SysUser();
        BeanUtils.copyProperties(user, userPO);
        ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(130, 34, 6, 2);
        String password = captcha.getCode();
        userPO.setPassword(new BCryptPasswordEncoder(6).encode(password));//密码
        userPO.setCreateBy(user.getUsername());
        Random random = new Random();
        int s = random.nextInt(6) % (6 - 1 + 1) + 1;
        userPO.setAvatar("assets/tmp/img/" + s + ".png");//头像
        userPO.setLabel("user");//注册用户初始为user角色
        this.save(userPO);
        // 没有设置成功
        ResponseData<Boolean> roleResponse = roleFeignFacade.userRegistered(userPO.getId(),userPO.getUsername());
        if (roleResponse == null || roleResponse.getData() == null || !roleResponse.getData()) {
            this.removeById(userPO.getId());
            return new ResponseData<>(ResponseCode.ERROR, "角色设置失败");
        }
        if (StringUtils.hasText(user.getPlatId()) && null != user.getPlat()) {
            SysThirdPartyUser thirdPartyUser = new SysThirdPartyUser();
            thirdPartyUser.setDeleted(Boolean.FALSE);
            thirdPartyUser.setCreateTime(new Date());
            thirdPartyUser.setPlatId(user.getPlatId());
            if (StringUtils.hasText(user.getUnionId())) {
                thirdPartyUser.setUnionId(user.getUnionId());
            }
            thirdPartyUser.setPlatSource(user.getPlat());
            thirdPartyUser.setUserId(userPO.getId());
            thirdPartyUser.setUsername(userPO.getUsername());
            thirdPartyUserService.save(thirdPartyUser);
            thirdPartyUserService.lambdaUpdate().set(SysThirdPartyUser::getUserId, userPO.getId())
                    .set(SysThirdPartyUser::getUsername, user.getUsername()).eq(SysThirdPartyUser::getUnionId, user.getUnionId()).update();
        }
        if (sendMessage) {
            Map<String, Object> message = new HashMap<>(8);
            message.put("id", userPO.getId());
            message.put("account", userPO.getUsername());
            message.put("password", password);
            rabbitTemplate.convertAndSend(PASSWORD_CHANNEL, PASSWORD_ROUTING, message);
        }
        return new ResponseData<>(ResponseCode.SUCCESS.getCode(), "注册成功", userPO.getId() + "");
    }
}
